stdlib-377.md
August 2, 2026 · View on GitHub
Context
The keyframe/track and skeletal-animation vocabulary in stdlib/graphics is aspirational: it
has no bodies, no runtime counterpart, and three of the eight remaining LINT001 findings
(plato-376) come from AnimationTrack/TangentTrack/NamedTrack obligations that cannot be
discharged from the library side at all. It belongs in stdlib/future, the tier reserved for
vocabulary that is declared but not yet shipped.
Once it is there, future as a whole should stop being converted to C# and stop being linted:
both gates measure content that nobody is trying to make shippable yet, and the noise hides real
regressions in the three shipping tiers. It must still PARSE and TYPE-CHECK — that is the
property that keeps the aspirational vocabulary honest.
Decisions
TimeVarying<TValue>stays ingraphics(astime-varying.concepts.plato/time-varying.library.plato):TweenandOscillatorinmotion-graphics*.types.platoimplement it, and nothing in a shipping tier may reach intofuture.- Default tier list for lint and codegen is
foundation, geometry, graphics.futureis added back by an explicit opt-in flag (-IncludeFuturein the PowerShell gates,--include-futureintools/record-gates.py). - Type-checking keeps enumerating all four tiers, recursively:
ForwardStdLibParsesAndCompilesandForwardStdLibDiagnosticCountDoesNotRegressare unchanged.
Done means
- Animation-track and skeletal-animation declaration files live under
stdlib/future -
TimeVaryinginterface + bodies remain ingraphicsand no shipping-tier file references afuturedeclaration -
lintand C# codegen skipfutureby default and include it behind an explicit flag -
futurestill parses and type-checks (all four tiers, 0 diagnostics) - Lint ratchet ceiling lowered to the newly measured value in the same commit (44 -> 38)
-
stdlib/README.md,stdlib/LIBRARIES.mdandAGENTS.mddescribe the new default
Result
Measured 2026-07-31 (python tools/record-gates.py --full --dry-run):
| gate | result |
|---|---|
| Plato.CLI build (Release) | PASS |
| lint --strict (three shipping tiers) | PASS — 0 error / 38 warning / 1486 info, ratchet 38 |
| PlatoTests (both ratchets) | PASS — 197 passed / 0 failed |
| forward-stdlib codegen (full recipe) | PASS — 1322 .g.cs, 31 degraded bodies |
Re-measured later the same evening, after the Generated/ cleanup below: lint ratchet 33,
PlatoTests 200/200, codegen PASS at 1052 .g.cs (the drop is plato-378's intrinsics pruning
landing in the same tree, not this change), and the stale-file CS0246 cluster is gone.
forward conformance (build + law runner) is RED for an unrelated in-flight reason — 12 x
CS0102 in src/Plato.Intrinsics/Integer.cs and Number.cs, where Zero/One are now defined
both by hand and by generated constants. That belongs to plato-378's primitives split.
TimeRemap.Track: AnimationTrack<Number> became TimeRemap.Curve: TimeVarying<Number>: it was
the one shipping-tier reference into the moved vocabulary, and the interface is what it always
meant. The existential is object-safe, so ForwardStdLibHasNoViewlessExistentialReferences
(CHK308) stays green.
Two defects surfaced and were fixed in passing, since both blocked verifying this change:
tools/check-stdlib-fast.ps1andtools/stage-stdlib.ps1still used pre-reorg project paths (Plato.CLI\...rather thansrc\Plato.CLI\...), so the inner-loop gate could not run at all. This is the Plato-side twin ofplato-372.tools/record-gates.pynever emptied the conformanceGenerated/folder, so.g.csfiles from a previous, wider generation kept compiling into the suite. Dropping a tier made that visible as CS0246 onGeoRegion<>/TimeSampled<>; the same trap would fire on any rename.