Sparkwing — an ed-tech dimension map
Sparkwing is a fictional mentored-project-learning platform for K-12 students — mentor pairing, a project-sector chat advisor, an auto-grading sandbox, portfolio certification, and parent progress updates. It's kept deliberately smaller than Meridian: five agents, no MCP layer, one language. The point of this fixture is the pitch, not the feature count — every one of Sparkwing's real product surfaces maps onto a specific Stoa risk dimension, with file:line evidence, not a generic checklist applied after the fact. The full source is in examples/sparkwing.
Architecture
staff (confirms) → mentor_matcher (LangGraph, recommend-only, golden baseline)
student chat → sector_advisor (framework-free, raw loop)
submission → project_sandbox (LangChain, runs a model-suggested shell
check with no sandbox construct)
submission → portfolio_certifier (LangChain, decides + writes the badge
outcome straight to the DB, no gate)
weekly cron → progress_notifier (LangChain, SendGrid + third-party HTTP)
Every real feature, mapped to a dimension
| Real feature | Agent | Planted finding(s) | Dimensions lit |
|---|---|---|---|
| Mentor pairing (staff-confirmed) | mentor_matcher |
none — golden baseline | contrast case |
| Project-sector chat with a student | sector_advisor |
AI001, AI005 floating-alias, AI007 | injection-tamper-surface, dependency-drift, conduct-variability |
| Portfolio badge certification | portfolio_certifier |
AI002/sql, AI003, DECL001 | output-fidelity, unreviewed-high-impact-action, mandate-overreach |
| Auto-grading sandbox | project_sandbox |
AI002/exec (gate-eligible), CTRL006, DECL006 | mandate-overreach, unreviewed-high-impact-action, control-coverage-gap |
| Parent updates + usage sync | progress_notifier |
AI006, REL001, NET002 | boundary-leakage, control-coverage-gap |
Resulting matrix, from a real scan: mandate-overreach and unreviewed-high-impact-action reach elevated — driven entirely by the contradiction detector below — while boundary-leakage, output-fidelity, and injection-tamper-surface reach moderate. Conduct-variability and dependency-drift correctly stay low: they're proxy dimensions, capped below elevated by design, never claiming to have measured runtime behavior from a config signal alone.
The contradiction detector, twice
portfolio_certifier is declared human_approved in
stoa-declared.toml — a second set of eyes on every badge outcome, per policy. The scan
finds no such thing: the model's verdict is interpolated straight into an UPDATE
(AI002/sql, critical) with no approval construct anywhere in the file, so the scanner infers
unrestricted_autonomous. DECL001 fires with both sides cited — the
code evidence and the exact declaration key it contradicts. A self-attested questionnaire can't
catch this; a same-run cross-check can.
project_sandbox isn't declared at all. It's a real scanned agent — the
auto-grading harness runs a model-suggested shell command with no sandbox construct (CTRL006), and
that command is gate-eligible on its own (AI002/exec, the one finding here that fails
stoa scan --strict unassisted). Nobody wrote it into stoa-declared.toml.
DECL006 names exactly that gap.
stoa scan examples/sparkwing, or read the
dimension-by-dimension risk map
and the
verification log
— every finding on this page was confirmed against a live scan, not asserted from a docstring.
Pre-generated output is committed in
sample-output/.