Daniel sent us this one — he wants to know how you'd build an AI programming tutor that assigns complete projects, reviews finished work, and develops a persistent understanding of the learner over time. Not another code generator that hovers over every line, but something that feels like getting a brief from a professor, working independently, and then receiving detailed, honest feedback. And he wants the full architecture — intake assessment, competency graphs, sandboxed execution, multi-stage review pipelines, the whole thing.
This is exactly the right question at exactly the right moment. You've got platforms like Replit and CodeSignal Learn racing toward adaptive project-based learning, but as of mid twenty twenty-six, nobody has really solved persistent learner memory or truly autonomous project review. The gap between what exists and what's possible is enormous.
The gap between what people think they're learning when an AI writes their code for them and what they actually retain — that's even wider.
That's the tension at the heart of this. The vibecoding era has produced a generation of people who can ship things they don't understand. Daniel's asking about the inverse — a system that teaches you to not need it.
Let's unpack what this system would actually look like, starting with the core problem it's trying to solve.
Traditional programming education oscillates between two poles that both fail in different ways. On one end, you've got toy exercises — calculators, to-do lists, number guessing games. They're pedagogically sound in the sense that they isolate specific concepts, but they bore anyone who's motivated by building things they actually want to use. On the other end, you've got real projects that are genuinely engaging but overwhelming for beginners because they require a dozen concepts the learner hasn't encountered yet.
The classic "build a Twitter clone" as your first project problem. You don't know what a database is, but here's your user authentication system.
And what Daniel's proposing inverts that model. Instead of picking a project and hoping it matches the learner's level, you start with an intake interview that assesses actual ability, then assign a project calibrated to where they really are.
The three pillars here are adaptive project assignment, autonomous code review with LLM analysis, and persistent educational memory that tracks concept mastery over time. And the key design constraint — and this is where most AI tutoring systems get it wrong — is that the system should not be a pair programmer commenting on every line as it's written. It should feel like receiving a brief, working independently, and getting a professor's detailed feedback after submission.
That asynchronous model mirrors how real software development actually works. Nobody stands over your shoulder narrating your keystrokes. You get a task, you figure it out, you submit it for review. The learning happens in the struggle and in the feedback, not in the moment-by-moment handholding.
The first challenge is figuring out where the learner actually is — not where they say they are.
Self-reported experience is nearly useless for placement. Every educator knows this. Someone will say they're "intermediate" because they completed a tutorial, but they can't write a function from scratch. Someone else will say they're a "beginner" because they're humble, but they've been writing scripts for two years.
The Dunning-Kruger effect meets impostor syndrome, and the system has to sort out which is which.
The intake needs to estimate actual ability through a multi-modal diagnostic. I'd design three components. First, code-reading questions — present a short function and ask what it does. This tests comprehension without requiring the learner to produce syntax from memory. Second, debugging tasks — here's five lines of Python with a bug, find it and fix it. Third, a small live-coding exercise in a sandboxed environment — something constrained enough to be completable in ten minutes but open-ended enough to reveal how the learner thinks.
None of this should feel like an exam. The framing matters enormously. If the intake feels like a test you can fail, learners will be anxious and perform worse. If it feels like a conversation about what they know and what they want to build, you get more honest signals.
The live-coding exercise in particular needs careful design. You're not grading the output — you're observing the process. Does the learner write tests first? Do they reach for list comprehensions or write explicit loops? Do they handle edge cases unprompted? These are signals about where they actually are on the competency ladder.
Which brings us to how you represent that competency ladder in the first place. Daniel asked about the data model for learner knowledge.
I'd build a competency graph — a directed acyclic graph where each node is a specific concept and edges represent prerequisites. So "list comprehensions" depends on "for loops" and "lists." "Decorators" depends on "functions as first-class objects" and "closures." "Context managers" depends on "classes" and "exception handling.
Each node stores more than just a binary "knows it or doesn't.
Each node tracks at minimum: whether the concept has never been encountered, whether there's theoretical understanding but no applied mastery, the count of successful applications across different contexts, the mistake count, and a timestamp of when it was last practiced. The distinction between theoretical understanding and applied mastery is crucial — it's the difference between being able to explain what a decorator is and being able to write one that actually works in a real codebase.
Then there's the temporal dimension. A single error versus a recurring weakness versus a genuine misconception — those are different categories of problem that require different responses.
This is where temporal tracking becomes essential. If a learner makes the same class of error across three different projects in different contexts, that's not a typo and it's not a one-off mistake — it's a misconception. The system needs to recognize that pattern and intervene differently than it would for a single slip. A one-time off-by-one error gets a note in the feedback. The same off-by-one error across a loop, a slice operation, and a range call across three projects? That triggers a targeted intervention — probably a short diagnostic exercise specifically about indexing conventions before the next project assignment.
Then there's the category Daniel mentioned that I think is the hardest to handle well — stylistic preference versus actual problems. Two experienced developers can disagree about whether a list comprehension is more readable than a for loop in a given context. The system needs to know when to flag something and when to say "this works, it's just not how I'd write it.
That's where the rubric needs explicit weighting. Correctness is non-negotiable — it's forty percent of the score. But idiomatic Python is only five percent, and the feedback should explicitly label stylistic suggestions as preferences, not requirements. "This works correctly. Here's an alternative approach you might consider for readability." That's very different from "this is wrong.
The intake places the learner on this graph, and now the system needs to assign a project. How does that work?
I'd use a hybrid approach — a curated library of roughly fifty project templates with adjustable complexity parameters. A command-line to-do app, for example, can be basic file I/O with a text file, or it can include SQLite, argparse, and a testing suite depending on which parameters you dial up. The system selects a template that targets concepts just beyond the learner's current mastery boundary — what Vygotsky called the zone of proximal development — and then personalizes the theme based on the learner's stated interests from the intake.
If someone says they're into music, the to-do app becomes a setlist manager for bands. Same concepts, different skin.
And that personalization matters more than you'd think for motivation. The learner is building something they can imagine using, even if the underlying pedagogy is the same. The template library approach also gives you quality control — you know the project is completable, you know what concepts it exercises, and you've pre-verified that the difficulty scaling works. Pure dynamic generation of projects from scratch is too unpredictable for a system that needs to guarantee educational coherence.
Let's talk about the GitHub workflow, because this is where the rubber meets the road on the "work independently" model.
The workflow Daniel described is clean. The agent creates a private repository from a template, opens an issue with the assignment brief, and then monitors commits through GitHub's API. When the learner opens a pull request, that's the submission signal — it triggers the review pipeline.
The permissions model?
This is where GitHub Apps are vastly superior to OAuth tokens. You can request repository-scoped permissions that limit access to only the repos the app creates. The minimum viable permission set is: Contents write to create repos from templates and push review branches, Issues write to post assignment briefs, and Pull requests write to leave review comments. That's it. The app has no access to the learner's other repositories, no access to organizations, no ability to read anything it didn't create itself.
The nightmare scenario of "I granted access to an AI tutor and now it can read my company's private repos" is architecturally impossible.
And the agent can push a review branch with suggested patches and leave inline PR comments, which means the feedback lives where developers already expect it — in the pull request. The learner can accept suggestions with a click, discuss specific lines, and iterate. It's the same workflow they'd use in a professional code review.
Once you know what the learner knows and they've submitted work, the next question is how to safely and thoroughly review it.
The review pipeline has to handle something most code-execution platforms avoid — running arbitrary, untrusted code that might be actively malicious or just accidentally destructive. This is not a hypothetical. Beginners write os.system('rm -rf /') without understanding what it does. Sometimes they copy-paste it from a bad tutorial.
Or they install a package that looks useful but has a malicious post-install script.
The execution environment needs real isolation. I'd use gVisor — it was open-sourced by Google in twenty eighteen and provides application-level kernel isolation by intercepting syscalls. Even if the learner's code tries something destructive, it hits a seccomp policy that blocks it. The performance overhead is about five percent compared to native execution, which is negligible for the scale of code we're running.
Firecracker is the other option — the micro-VM technology AWS Lambda uses.
Firecracker boots in about a hundred and twenty-five milliseconds and provides hardware-level isolation, which is even stronger. The tradeoff is slightly more infrastructure complexity. For a production system, I'd probably use Firecracker. For a prototype, gVisor is simpler to deploy.
What does the sandbox configuration actually look like?
Each review spawns an ephemeral container with no network access except to a private PyPI mirror — that way the learner can install dependencies but only from a pre-vetted allowlist. Two hundred fifty-six megabytes of RAM limit, a five-second execution timeout, and a read-only filesystem except for the temp directory. If the code hasn't produced output in five seconds, the container is killed. If it tries to allocate more memory than the limit, it's killed. These constraints also teach good habits — efficient code that doesn't leak resources.
The review itself has multiple stages before the LLM even looks at the code.
First, static analysis — pylint for style and potential errors, mypy for type checking, and bandit for security scanning. Bandit will flag things like use of eval, hardcoded passwords, or unsafe deserialization. Second, test execution — if the learner included tests, run them and capture the output. Third, the LLM-based review.
The LLM receives all of that context — the diff, the static analysis results, the test output — and evaluates against a structured rubric.
The rubric has weighted criteria. Correctness is forty percent — does the code actually do what the assignment asked? Structure and organization is twenty percent. Error handling is fifteen percent. Documentation is ten percent. Testing is ten percent. Idiomatic Python is five percent. Those weights tell the LLM what to prioritize, and they also tell the learner what matters. Correctness dominates because a beautifully structured program that doesn't work is still a failure.
The output is structured JSON, not freeform prose.
Structured JSON that includes: strengths, maximum three, prioritized by significance. Weaknesses, maximum five, ordered by severity. Annotated code snippets with suggested fixes. And a "concepts to reinforce" list that feeds directly back into the competency graph. The five-weakness cap is deliberate — more than that and the learner is overwhelmed. A good human instructor knows to focus on the highest-impact issues, not exhaustively catalog every imperfection.
This is where Daniel's question about feedback modality gets interesting. A written report with annotated diffs is the baseline, but he asked about audio walkthroughs, generated video lessons, even a personalized podcast episode discussing the submission.
Some of these are achievable today and add real educational value. Others are novelty. An audio walkthrough linked to specific files and line numbers — that's doable with ElevenLabs or OpenAI's TTS APIs, both of which can generate natural-sounding speech from text with latency under two seconds for short passages. You generate the written feedback, convert it to audio, and the learner can listen while looking at their code.
That's actually useful for learners who absorb information better by hearing than reading. It's not just a gimmick.
An interactive code-review interface — where the learner can click on a flagged line, see the feedback, and accept or discuss suggestions — that's probably the most educationally valuable format. It turns passive review into active engagement. But a generated video lesson based on the learner's mistakes? That's harder to do well. You'd need to generate slides, synchronize narration, and the production quality would be inconsistent. It's achievable but the value-add over an interactive interface with audio is marginal.
The personalized podcast episode — I appreciate the ambition, but that feels like a fun demo that doesn't actually improve learning outcomes compared to a well-structured written review with audio option.
The format I think is most underrated is the follow-up debugging session. After the learner has received feedback and attempted fixes, the system initiates a conversation about what they changed and why. That's where you detect genuine understanding versus pattern-matching. If the learner can explain their reasoning verbally, they've internalized the concept.
Which connects to the hardest problem Daniel raised — detecting when a learner is using AI to complete assignments.
There's no perfect detection method, and anyone who claims otherwise is selling something. But you can flag suspicious patterns. Perfect code from someone whose intake showed beginner-level ability. Code that matches the stylistic fingerprints of LLM output — certain comment patterns, variable naming conventions, the particular way ChatGPT structures error handling. Sudden jumps in complexity between assignments that don't match the learning velocity curve.
The giveaway isn't any single signal — it's the combination of signals that don't fit the learner's established trajectory.
When the system flags a submission, the response shouldn't be punitive. It should be a follow-up conversation. "This is strong work — can you walk me through your approach to the error handling in this function?" If the learner can explain it, great — maybe they're just improving fast. If they can't, that's a learning moment, not a gotcha. The system can say "it looks like you may have had help with this section, which is fine, but let's make sure you understand what it's doing.
The goal isn't to catch cheaters. It's to ensure learning is actually happening. If someone used AI to write code they can now explain and modify, they learned something. If they can't explain it, they didn't.
Now let's talk about persistent memory, because this is what separates a tutor from a tool. Daniel asked what should be stored and how.
Three-tier storage seems right. Relational database for structured data — learner profiles, completed projects, scores. Graph database for the competency graph. Vector store for embedding-based retrieval of past feedback.
PostgreSQL with pgvector covers two of those tiers in one system, which simplifies the prototype considerably. pgvector was released in twenty twenty-one and enables vector similarity search directly within PostgreSQL. You don't need a separate vector database. For the graph component, Neo4j is the natural choice — it can traverse competency prerequisite chains in logarithmic time using index-free adjacency, which matters when you're computing what concept to introduce next based on multiple prerequisite paths.
For a prototype, you can implement the graph as adjacency lists in PostgreSQL and add Neo4j later. The graph traversal performance isn't the bottleneck when you have one learner — it matters at scale.
The most interesting piece of the memory architecture is the summarization agent. You don't want to store every interaction forever as raw events — that becomes unwieldy. Instead, a weekly agent compresses the event log into a learner snapshot that captures current mastery state, common error patterns, and learning velocity. The snapshot is what the assignment-sequencing algorithm reads, not the raw event stream.
Learning velocity is a metric I haven't heard discussed enough. It's not just "what does the learner know" but "how fast are they acquiring new concepts." Two learners might have the same current mastery state but very different trajectories.
That velocity signal should influence assignment difficulty. A learner who's acquiring concepts quickly gets projects that stretch further beyond their current boundary. A learner who's struggling gets projects that consolidate existing knowledge before introducing new material. The system adapts not just to static ability but to the rate of change.
Let's talk about the assignment sequencing algorithm itself. Daniel asked how the system decides what comes next.
I'd use a modified Bayesian Knowledge Tracing model. The original BKT was formalized in nineteen ninety-five by Corbett and Anderson for the ACT-R cognitive architecture, and the core idea is that you maintain a probability that the learner has mastered each concept, updating it after each observation. When a learner demonstrates mastery — three consecutive correct applications across different contexts — the probability updates from, say, zero point three to zero point seven. If the concept isn't practiced for four weeks, the probability decays by about zero point zero five per week.
Mastery isn't binary and it isn't permanent. The system knows that knowledge decays without practice.
Which is why the sequencing algorithm includes spiral review. After a concept hasn't been practiced for several weeks, the system deliberately schedules a project that requires that skill — but in a new context, so it's not repetitive. The learner might have mastered list comprehensions in the context of data processing, but now they need to use them in a web scraping project. Same concept, different application, and the system gets a fresh observation of whether the mastery transferred.
The decay model also means the system can answer questions like "has this learner actually retained what they learned three months ago, or did they just perform well in the moment?
That's the difference between immediate mastery and long-term retention, and most educational platforms don't measure the latter at all. They tell you you've "completed" a concept and never check again. A tutor with persistent memory can say "you understood this in March, but you struggled to apply it in July — let's reinforce it.
If you wanted to build this tomorrow, what would you actually ship?
The simplest credible prototype is: a GitHub App with the minimal permission set we discussed, the OpenAI API for the LLM-based review, a gVisor sandbox for code execution, PostgreSQL with pgvector for structured data and vector search, and a basic web dashboard for the learner to see their progress and feedback. That's it. Five components, all of which exist and work today.
What do you defer?
Defer multimodal feedback — start with written reports and annotated diffs, add audio later. Defer Neo4j — use PostgreSQL adjacency lists for the competency graph in the prototype. Defer automated spiral review — use simple spaced repetition scheduling instead of full Bayesian Knowledge Tracing. Defer the interactive code-review interface — start with a static web page that renders the feedback JSON. The prototype should demonstrate the core loop: intake, assign, submit, review, remember, repeat. Everything else is optimization.
What separates a demo from a effective system?
First, the quality of the competency graph. It has to capture not just what concepts a learner knows but the relationships between them. If the graph says "decorators" depends on "functions as first-class objects" but misses that it also depends on understanding closures, the system will assign projects the learner can't complete. The graph is the curriculum, and building it well requires actual pedagogical expertise, not just technical skill.
The feedback has to be specific enough that the learner can act on it without additional help. "Your error handling could be improved" is useless. "In the parse_config function on line forty-seven, you're catching a generic Exception — catch the specific ConfigError instead, and handle the case where the config file exists but is empty" — that's actionable.
The system has to track long-term retention, not just immediate mastery. Most platforms optimize for the feeling of progress — badges, streaks, completion percentages. A real tutor optimizes for whether you still know it six months later. That requires persistence and patience that most products don't have.
How would you evaluate whether it's actually working?
Project completion rate — are learners finishing what they start? Reduction in repeated errors across projects — is the feedback actually changing behavior? Time-to-completion trend — for projects of similar difficulty, is the learner getting faster? And the hardest to measure but most important: transfer ability. Can the learner apply concepts in an unfamiliar project context they haven't seen before?
That last one is the real test. If someone can only write list comprehensions in the exact format they were taught, they haven't really learned list comprehensions — they've memorized a pattern.
Transfer is what separates education from training. Training teaches you to perform a specific task. Education teaches you to reason about a domain. An AI tutor that only produces people who can complete the tutor's assignments has failed.
Even with all this architecture, there's a deeper question about what we're actually teaching.
The question Daniel's prompt implies but doesn't state directly: will learners actually engage with a system that gives honest, critical feedback? Or will they gravitate toward AI tutors that are endlessly encouraging and tell them everything they write is brilliant?
The market incentive pushes toward the latter. An AI that says "great job!" regardless of quality gets better retention metrics than one that says "this function has three edge cases you missed.
Yet the honest feedback is what produces actual improvement. A good human instructor is specific, prioritized, candid, encouraging where justified, and focused on a manageable number of improvements. They don't flatter you and they don't demolish you. They tell you what's working, what's not, and what to focus on next. That's the tone the system needs to hit.
The bigger picture here — and I think this is what Daniel is really getting at — is that as AI code generation becomes ubiquitous, the ability to independently design, debug, and reason about software becomes more valuable, not less. A good tutor teaches you to think, not just to ship.
The question is which application we prioritize. Right now, the market is pouring billions into AI that writes code for you and almost nothing into AI that teaches you to write code yourself.
If you're building something in this space, the key insight from everything we've discussed is that memory and honest feedback matter more than fancy UI or multimodal gimmicks. The system that remembers what you learned six months ago and tells you what you actually need to hear — that's the one that changes how people learn.
The path from prototype to production is shorter than it looks. GitHub App, LLM API, sandbox, database, web dashboard. The hard part isn't the technology — it's the pedagogical design. Building a competency graph that reflects how programming concepts actually depend on each other. Writing rubrics that produce actionable feedback. Designing intake assessments that measure real ability. Those are human expertise problems, not engineering problems.
The engineering enables it, but the teaching makes it work.
Now: Hilbert's daily fun fact.
Hilbert: In the eighteen forties, a British naturalist in Guyana documented a species of ant that constructs living bridges using their own bodies, but what's less known is that a local mathematician, working independently, developed a notation system for describing these bridge topologies using symbols borrowed from Guyanese weaving patterns — the only known instance of entomology influencing mathematical notation before the twentieth century.
An ant-bridge notation system from eighteen-forties Guyana.
This has been My Weird Prompts. If you're building something in the AI education space, we'd love to hear about it — email the show at show at my weird prompts dot com. I'm Corn.
I'm Herman Poppleberry. Go build something that actually teaches.