Repository navigation
docs: page-by-page review of the documentation - #953
Conversation
First page of the page-by-page documentation review.
index.md
- Motivation: one dense paragraph split into four.
- Basic usage: a transition line before the "each step has its own guide" list.
- Mathematical formulation: the Mayer term reworded as a boundary/pointwise cost
on the initial and final times and states and the optimisation variables, not
just the final state.
- Testing: one dense paragraph split into three.
- Reproducibility: dropped the `_downloads_toml` helper and three raw-HTML
`<details>` blocks (one emoji used twice); now a lead paragraph, a two-row
table for the two project files, and one `::: details` block holding
versioninfo / Pkg.status / Pkg.status(manifest).
Logo
- `logo.png` -> `logo.svg` (cropped artwork from .extras/logos/logo-gagnant/).
- Home page dark mode: an exact light/dark SVG pair. `docs/make.jl` generates
`logo-dark.svg` from `logo.svg` (white backdrop -> #1b1b1f, Julia colours
unchanged), git-ignored; two <img> with a plain display toggle.
- Navbar: single `/logo.svg` recoloured in dark mode by a `.dark` filter (24px,
the ~10% desaturation is imperceptible; a light/dark <img> pair double-renders
in the DocumenterVitepress navbar title).
Environment download (fixes a live 404 on the dev site)
- VitePress does not bundle `.toml` referenced from a Markdown link, so the
Project.toml / Manifest.toml download links have been 404 on `dev` since the
DocumenterVitepress migration. `docs/make.jl` now copies each into
`src/public/assets/` (served verbatim) as well as `src/assets/` (Documenter's
link check). `src/public/` is git-ignored.
Dark-mode figures
- `.dark .vp-doc img[alt=""] { filter: invert(0.894) hue-rotate(180deg) }` in
style.css: a = 1 - 27/255 lands white on the VitePress dark surface. Catches
every local `![]` image (DVP drops their alt); exclude one with a `@raw html`
`<img alt="...">`.
Plan and per-page log: .reports/documentation-review-2026-09.md (git-ignored).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Status: page 1/45 ( This first commit is larger than the following ones will be — besides the Next: |
Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…on; add Makie - Flows: OrdinaryDiffEqVern9 does not exist (OrdinaryDiffEqVerner does), and a non-Tsit5 integrator only works with OrdinaryDiffEqTsit5 still loaded (CTSolvers.jl#230). The warning becomes a tip with a verified alg= example. - Solver table: the :madnlp row no longer contradicts the GPU section. - Show a real ExtensionError transcript in the current boxed format. - Plotting: mention Makie; describe the missing-package errors precisely. - GPU: keep the three packages and CUDA.functional(), drop internal extension names and version history (kept on the GPU page). - Remove the page's Draft = false review marker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The home page already shows the bare code, so this page becomes the annotated version: the wagon story and figure, a line-by-line reading of the @def block, how to read the solve output and the plot panels, and a "Check it" section that compares the numerical solution with the exact one (u = 6 - 12t, J = 6). Hidden @asserts make the build fail if the solution drifts. Also: x = (q, v) in the code as in the maths, no "bounded" force, and the "1-D is a scalar" link now lands on the Control section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…asserts
- Binder badge (dead branch, uncommitted notebook) replaced by downloads: Literate
writes the notebook and the script to src/public/assets/, linked in raw HTML
because Documenter rewrites ../assets Markdown links to a 404 path.
- Notebook links: stable/ (404) -> dev/; tutorial link to tutorial-iss.html.
- CTLie in the ecosystem list; Installation link; callback argument v -> var;
NLP variables up to u_{N-1}; link texts match page titles.
- Goddard: Ipopt and MadNLP reach the same r(tf); grid-continuation prose
without hard-coded counts; bang-bang gain computed and explained, with an
altitude-vs-time figure built from time_grid/state.
- GPU: neutral prose, CUDA warnings silenced, prints CUDA.functional().
- PMP introduced once; u_max -> u_feedback; OrdinaryDiffEqTsit5 loaded once.
- Hidden @asserts: J = 6, r(tf), MadNLP vs Ipopt, cascade iterations,
bang-bang altitude, p0 = (12, 6).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- x ∈ ℝⁿ, u ∈ ℝᵐ, v ∈ ℝ^q are defined (m and k were used undefined). - Name the constraint kinds; mention → max and autonomy. - New "Notation and conventions" section, the single reference for the indirect-method pages: pseudo-Hamiltonian H and maximised Hamiltonian 𝐇 (PseudoHamiltonian / Hamiltonian), maximum principle, state constraints c(x) ≥ 0 with + μ c, minimal time in Mayer form (𝐇(t_f) = 1), and the variable costate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed rules - New "Structure of a definition": declarations first (the variable before the time when the bounds use it), the two named forms, and when names are read (constants at build time, functions at solve time). This replaces two contradictory notes on defining names before or after the block. - One table for the ASCII alternatives (in, R^2, derivative, integral, <=, =>). - Labels: dual(sol, ocp, :label) works, a number (1) is stored as :eq1 (new anchor results-solution-duals on the solution page). - Constraint kinds named box / general instead of linear / nonlinear; the "damped" integrator is now damped (- c(t) v(t)). - Known upstream problems as one-liners: CTParser#352 (generic hint), #353 (single = in the dynamics), #354 (gensyms in trace mode). - Known issues section removed: the #481 examples all solve with the current versions. - Warnings shown without the local package path; wording fixes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The functional API page lays out each @def model beside its functional twin with .responsive-columns-40-60, a class only defined in custom.css, which the VitePress theme never loads: the columns were stacked on the live site. The rule moves to style.css; narrow screens stack the two columns instead of hiding the second one. custom.css held nothing else that style.css lacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ence - Problem 7: the velocity bound is a labelled box (v(t) ≤ VMAX, and constraint!(pre, :state; rg=2:2, …)) instead of the "+ 0.0" path constraint, whose justification was wrong. - Problem 1 loads Plots before plotting; its @def body is indented. - Hidden asserts: macro and functional forms reach the same cost (or the same λ) on all seven problems; J = 6, t_f = 2, λ ≈ 0.5 where known. - No typeof output, no test-file path, no "one place on the site" claim; "Mayer (boundary) cost", "general" constraints, "optimised". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Title and sidebar: "Control-free problems" (was "No control"). - Drop the implementation details (EmptyControlModel, dispatch on the control field's type), shown twice; show is_control_free(ocp) instead. - The harmonic oscillator is now solved: ω = π/2 is recovered. - Hidden asserts: λ ≈ 0.5, ω ≈ π/2. - "Adding a control back" removed: it described two Flow guards, which belong to the Flows pages (constrained-arcs already shows the second one). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s vs times - Autonomy: a path constraint depending on t also makes the problem non-autonomous (stated twice, now with an executed example). - The label (1) is stored as :eq1, with a link to Labels. - times(ocp) is a struct, times(sol) a vector: say so. - Evaluation points no longer reuse the model's names q, u, v. - The final_time / mayer error hints are not helpful yet: CTModels#431. - "API trap: time is gone" becomes "times, not time", without history; the alias note moves to the end; no internal type names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… claim - The prompt and the four "Try with" buttons pointed to stable/, a 404 until the next stable release: now dev/ (no trailing dot in the prompt). - The AI answers are @example blocks: the build constructs and solves them (minimal time tf ≈ 6.5; the rocket reaches the guided tour's Goddard altitude), with hidden asserts. - The "compatible with ExaModels" follow-up is kept as a real exchange, but the page now shows that the vector form solves with :exa too. - No dated model name; the gallery has no rocket, link the guided tour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guided tour no longer offers a Binder badge: its notebook and script are downloads served with the docs. Nothing else used binder/. CHANGELOG and BREAKING keep their historical mentions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Solve overview" - "Reading the display" described :user/:default/:computed tags that the box never shows. It now walks through the actual Configuration box (as v2.0.4 did): options per strategy, [cpu-dependent] defaults, defaults hidden, describe for the full list. - display=false silences the solver log too: say so. - "Two ways to steer it": the rule for users (don't mix tokens and typed components) instead of the type-based mode detection. - "When it fails" shows a failed solve (max_iter=0: :max_iter, violation 1.1) next to a converged one, with hidden asserts. - H1 "Solve overview" (C8). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ct a guess - The short form `u := 2` is shown (the example did not use it) and the table lists every form, including grids. - v2.0.4 content restored: the labels/time-variable note, and the cross-spec rules with the constant → temporal, constant → constant and alias cases. - New: the named-tuple form (state/control/variable), and "Inspect a guess" with state/control/variable on build_initial_guess output (replaces a typeof printout). - variable on a solution is a scalar for a 1-D variable. - The init/initial_guess inconsistency becomes a one-liner (OptimalControl#964); the "not yet public API" maintainer note moves to OptimalControl#965. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/probes/ holds one script per page or section for claims that an executed block cannot show: errors when a package is not loaded, another environment (OrdinaryDiffEqVerner without Tsit5), user-session rules for @def, the absence of output with display=false, external URLs, and the #481 regression that justified removing "Known issues". run.jl runs each in a fresh Julia process with the docs environment. A probe for a known upstream bug checks the current behaviour, so it fails once the fix lands (CTBase#565, CTSolvers#230). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y, real errors - :exa accepts the vector form of the dynamics: the coordinatewise requirement is gone from the page; the shared problem is written in vector form and solved with :exa. - "Ambiguity" becomes "Incompatible tokens": the error is "no description contains all symbols", with the closest matches. - v2.0.4 content restored: the "Understanding default values" (NotProvided) note, describe for every modeler and solver (in details blocks), one-line scheme descriptions, and the official documentation links (ExaModels and MadNLP now under madsuite-org). - :di is the AD backend, :sciml the ODE integrator; the internal registry section is dropped; no authoring remarks. - Known upstream problems as one-liners: CTParser#355 (scheme aliases under :exa, the error shown is now the alias one) and CTDirect#638 (time_grid ignored or crashing under :exa). - Hidden asserts on methods(); probe solve_completion.jl checks the completion examples and describe(:sciml) / describe(:di). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…computed explained - The routing example uses a quiet modeler option (backend) instead of show_time, which flooded the page with timings. - No placeholder option: say that no two built-in strategies of a method share an option name today; route_to is shown executed, including its keyword form route_to(madnlp=1000). - :computed means "depends on the :cpu/:gpu parameter" (MadNLP's linear_solver), not "computed from the problem"; the display shows :user and :computed options, not defaults. Hidden asserts on option_source. - No internal type names (BypassValue, RoutedOption). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mport - discretizer / modeler / solver / sol everywhere (mod shadowed Base.mod, sol was a solver and result the solution). - "using CTDirect: Collocation would also work" removed: an indirect dependency cannot be loaded from a user environment. - The per-component example now solves with the components it builds (Gauss–Legendre on 50 steps recovers J = 6, hidden assert) instead of building unused ones with show_time=true. - No mode-detection internals; link texts updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… madsuite links - "The problem must be coordinatewise" is gone: :exa accepts the vector form of the dynamics and of path constraints (verified, same cost as :adnlp); the example problem uses it. - v2.0.4 content restored: the CPU vs GPU defaults (Exa backend, MadNLP linear solver) and the "beneficial for" list. The timing block now compares :cpu and :gpu at the same grid size on a GPU machine. - CUDSS warning without version history; the ExaModels name clash is still real (#882 closed, clash checked by a probe). - `parameter`, not `strategy`; modeler/solver names. - ExaModels and MadNLP moved to madsuite-org: page links and InterLinks updated, placeholder inventories replaced by the real ones (225 and 157 entries). - Probe solve_gpu.jl: "Missing CUDSS" error and the ExaModels clash. common.jl now mirrors make.jl's load path (docs environment first), which also fixes CUDA failing to load in the probes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…solutions - Check the trajectories, the objective and the free final time against the closed forms (hidden asserts); one minimum-time problem (t_f = 25/12) for the horizon and the duals, with labels that are not "eq_" on inequalities. - Explain that the direct costate is shifted by half a step, and that the multiplier of the initial condition gives p(t0). - Evaluate the dual accessors at a time instead of printing CoercedTrajectory; plot the path multipliers; state the box sign convention and its two differences with nonlinear constraints (CTDirect#639), and the zeros under :exa (CTDirect#405). - Restore the v2.0.4 intro, the print and plot of a solution, and the summary tables; variable(sol) is a number, a vector or an empty vector. - Show that a flow returns a Solution, and what it lacks (duals, iterations). - Drop the CTModels >= 0.18 history, the type-annotation paragraph and is_empty_time_grid. - Probe solution_duals.jl for the claims the build cannot execute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status: pages 1–16 of 45 pushedGetting started, Modelling and Solve are done (22 commits). Results has started: the Solution object page is committed locally, and will be pushed with the rest of the section. What changed, across the pages
Upstream issues filed
Once the CTSolvers and CTModels releases are out
NextResults (Plot, Plot with Makie, Save & load), then Flows, Geometry and the examples, where the remaining correctness items are (state-constraint example, shooting, multi-phase flows). |
… flow caveats - Restore the v2.0.4 opening (plot / plot! / plot!(plt, …)) and the argument overview table, with anchors for each section. - Constraints: a speed-limited thrust u + v ≤ 1 (a path constraint, not a box in disguise), with its analytic final time checked; say that boxes are drawn as bounds only. - control=:norm on a 2-D control (u = ((16 − 6t)/13, 6/13), J = 8/13 checked), not on a scalar. - title, xlabel and ylabel are set by plot and user values are ignored (CTBase#569): drop the ineffective xlabel="s", show the subplot workaround (hidden asserts). - Flow: start from the exact p(0) = (12, 6); the 5-point grid (CTFlows#435); saveat needs dense=false, otherwise the call crashes (CTFlows#434), checked by the new probe plot_flow_saveat.jl. - Real ExtensionError transcript; drop the redundant Styling section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…al path constraint - The diff block's error line is the bare plot(sol), not Makie.plot(sol) twice (B3). - The switching time of the minimum-time example is 1 + √2/2, read off the control and checked (with t_f = 1 + √2), instead of t_f/2. - OptimalControl exports RecipesBase's plot, not Plots'; the ambiguity hint also lists the modules loaded by the build. - The constraints example uses the speed-limited thrust of the Plot page instead of 1 ≤ v + 1 ≤ 1.8. - Shorten the 3 000-character type in the Makie.plot!(ax, sol) error; a phase portrait for the figure built from scratch; the flow starts from the exact p(0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt checked - File names: a name that already ends with the extension is used as is (B4; the doubling was fixed by CTModels#399), checked with isfile and cleaned up. - Both formats give back the same solution value for value (grid, state, control, costate, status): hidden asserts replace the vague claim that JSON is not exact; the choice is about the file (JLD2 compact, JSON readable anywhere, sizes shown). - The model passed to import_ocp_solution must be the original one; the error with another model is obscure (CTModels#435). - Real ExtensionError transcript; the warm start is solved and checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tory calls, no internals - H1 "Flows overview" (C8); the PMP recap uses the notation of Formulation (H, 𝐇, p⁰ = −1, the control maximises H) and links to it. - Derive the control law of the example (u = p_v) and execute both calls of the flow: the point call reaches the target with p(1) = (12, −6), the trajectory call returns a Solution with J = 6 (hidden asserts). - Drop the maintainer note on why the ExtensionError is not executed, and the paragraph on the internal get_full_strategy_registry. - describe(:sciml) and describe(:di) in collapsible blocks; saveat needs dense=false (CTFlows#434). - method=:gpu: what it selects (integrator, Mooncake AD backend, device arrays), the CTFlows GPU page, and the obscure errors without a GPU or Mooncake (CTFlows#436). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, Symbol form caveat - Restore the first-order example (ẋ = u, x ≥ 0.1, ∫x², Bonnard–Faubourg–Launay– Trélat 2003): derivation of u = 0 and μ = 2x on the arc, three arcs with t₁ = 0.9, t₂ = 1.6; the flow reaches x(2) = 1/2, and the direct method finds the same arc and the same cost (asserts). - Restore the costate-jump example (Bryson–Denham, l = 1/9, order two): derivation, jumps of 18 on p₁ at 1/3 and 2/3, J = 4/(9l) = 4 for both the flow and the direct method, overlaid on a plot. - Function form everywhere (decision C6), with the c([t,]x,u[,v]), u([t,]x,p[,v]), μ([t,]x,p[,v]) signatures; the `+ 0.0` trick is gone. The Symbol form is mentioned with its limitation: it ignores the bound and the side of the constraint (CTFlows#440, derivation and measurements in the issue). - With saveat, a flow's point call returns the value at the last saved time (CTFlows#441): warned on this page, on Plot and on Flows overview. - Drop the arbitrary t1, t2, p1 demo and the positional-form section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… from the direct solve - Transversality of the free final time written as in Formulation: for the Mayer cost t_f, p(t_f)·f = 1 (the page said H(t_f) = −1); the switching condition is "the switching function p₂ vanishes at t₁", not the circular "H_u = 0". - shoot! uses unsafe=true, as the page recommends. - The shooting starts from the direct solution: p₀ = dual(sol, ocp, :start), t₁ read off the control, t_f = variable(sol); Newton converges to p₀ = (1, 1), t₁ = 1, t_f = 2 (asserts), and the indirect and direct final times agree. - Drop the variable_costate example (p_v ≡ 0 there, since t_f only sets the horizon); link the section where the variable costate matters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status: Flows section done (28 / 45)Pages 23–28 are pushed (
New upstream issues
Probes11 / 11 pass. The new probes are Next
|
…dge identity derived and asserted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ump, CTLie#41 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riable forms, ∂ₜ section Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd checked, singular control derived Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wn, scope requirement → CTLie#40 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd constructed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ution derived, p₀ = (12, 6) and J = 6 asserted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Mayer transversality, (1, 1, 1, 2) asserted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/2 and p₀ = (0, −2) asserted, exact overlay Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, the ω = 0 extremal and why it is not optimal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… introduces after the review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ks, p₀ = −1, t₁ = 1, t₂ = 3/2, J = 3/8 asserted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bracket sign), non-degeneracy, all-singular extremal stated, asserts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ham regimes restored, analytic values asserted, references Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and Colors named, boundary values asserted, no .extras path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ted, augment and positional constraint now caught, user-facing tables Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e SolverFailure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
….19.6, CTSolvers 0.5.8, OrdinaryDiffEqVerner) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Status: review complete (45 / 45), ready for a final readAll 45 pages are reviewed and pushed (HEAD
Since the last status
New upstream issues
Notes for review
|
Page-by-page documentation review
A critical re-reading of every hand-written docs page, one at a time: correctness of every claim, prose and progression, links, and executed code. v2.0.4 is the reference: what it explained (derivations, analytic values, figures, summary tables) is kept, and the presentation is improved.
Draft until every page has been through. One commit per page.
Principles
@asserts, so a wrong value fails the build.docs/probes/(julia --project=docs docs/probes/run.jl). A probe for a known upstream bug checks the current behaviour, so it fails when the fix is released, as a reminder to update the page.Progress (45 / 45)
@Lie, AD backendMechanics
draft = trueand a@meta Draft = falsemarker on the page under review made only that page execute. Neither is committed:docs/make.jlhasdraft = false, as onmain..reports/(git-ignored).Before merging
draft = falseindocs/make.jl, full build green (every page executes).@meta Draftmarker left.julia --project=docs docs/probes/run.jlpasses (11 / 11), after updating the probes and notes of the upstream fixes released in the meantime.🤖 Generated with Claude Code