nix-bundle-lgx 6fb5d5b ("feat: add requirement for icons with manifest
0.4.0") validates the packaged icon straight out of the PNG IHDR: exactly
256x256, required for `type == "ui_qml"`. The tutorials embed a base64
placeholder that is 64x64, so `nix build '.#lgx'` now fails for calc_ui:
ERROR: icon does not match the Logos icon standard.
expected: PNG, exactly 256x256
actual: PNG, 64x64
That one rejection is the whole of the red run (208 passed, 3 failed):
`result-lgx/` is never created, so `Install the UI plugin` fails on a
literal `result-lgx/*.lgx`, and basecamp then launches without the plugin
("No clickable element found with text 'calc_ui'").
Regenerate the placeholder at 256x256, keeping the same solid #2ECC71. It
is now a 1-bit palette PNG rather than RGBA, which makes the embedded blob
shorter than the one it replaces (280 -> 144 base64 chars, 209 -> 106
bytes) despite the 16x pixel count.
The C++ UI tutorial carried the same 64x64 blob and was passing only
because its chain never reaches an `.#lgx` step — fixed here too, before
it surfaces.
Verified by extracting bundle.sh's validator verbatim and running the
tutorials' own `- run:` command through it: the old icon is rejected with
the exact CI error text, the new one passes.
outputs/*.md are hand-maintained (they carry deliberate /0.2.0 flake pins
that the generator does not emit), so the mirrored edits there are by hand
rather than regenerated.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
CI has been red on every run since the dependencies moved underneath it. The
repo itself has not changed -- master's HEAD IS the commit that last went green,
on 2026-07-22 -- but logos-tutorial has no flake.lock: the specs scaffold
projects that resolve `github:logos-co/...` fresh at run time, so the same
commit passes or fails depending on the day. Both failures below are the specs
asserting behaviour that upstream deliberately changed.
1. INTEGER WIDTH: `int` -> `qlonglong` in the generated Qt surface.
`lm methods` now reports `qlonglong add(qlonglong a, qlonglong b)` where the
spec expected `int add(int a, int b)`. This is the LIDL type contract: one
type per language, integers 64-bit throughout, no widening or narrowing.
The tutorial's explanation was not merely stale -- it documented the OLD
BUG as intended behaviour, telling the reader that their `int64_t` "shows up
as `add(int,int)`". That silent 64->32 narrowing is exactly what the type
contract removed. The bullet now says the width is preserved and why that
matters, which is the part a tutorial is for.
Only tutorial-wrapping-c-library asserts generator OUTPUT, so only it moves.
The `int` in tutorial-cpp-ui-app is C++ the reader writes themselves (`.rep`
SLOTs and their own `override` declarations), where the reader picks the
type -- that spec passes, and is deliberately left alone.
2. BASECAMP NAVIGATION: the Settings section was renamed and its tab removed.
`click("Modules")` failed with "No clickable element found with text
'Modules'". On basecamp master the section label is now "Module Inspector"
(SettingsView.qml:53), and the "Core Modules" tab is gone -- it was split
into its own view, which ModuleInspectorView.qml:18 says in as many words
("Formerly the 'Core Modules' tab of ModulesView"). So the tab-click step is
deleted rather than renamed, and the objectName the Interface screen is
opened through is `moduleInspectorView`, not `coreModulesView`.
Verified against origin/master of logos-basecamp, which is what CI builds:
`openInterface(name)` still exists (ModuleInspectorView.qml:46), and the
surrounding anchors "Settings", "Sections", "Dashboard" are all still there.
NOT ADDRESSED HERE, because it is not a tutorial bug: the third failure,
`persistenceDir` not containing `calc-data`, is a real regression in
logos-logoscore-cli. daemon_state.cpp:264 applies `--persistence-path` only
`if (cfg.dirs.data.empty())`, and dirs.data has a default -- so an explicitly
passed CLI flag loses to a default, silently. The spec is right and should
stay red until that is fixed.
The tutorial doc-test went red on ubuntu with
inspector not available on port 3768 after 120s
with `building '...-logos-standalone-app-1.0.0.drv'` as the last line of
the launch log: the app was still compiling when the clock ran out.
The runner pre-builds `nix run .` as `nix build .`, which is
packages.default — the UI plugin. But `nix run .` launches apps.default,
the standalone app, whose closure (logos-standalone-app plus the bundled
backend modules) is not covered by that warm build, so it compiles
during launch and is charged against the default 120s inspector wait.
Give the three `nix run` UI tests the same launch_timeout the
logos-wallet-module spec already uses for exactly this reason. Nothing
here is rendered into the generated Markdown.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* doctest: make the bad-bind step outcome-agnostic
Asserting status:error relied on the inner call to a missing module
blocking long enough to time out the outer RPC. With faster failure
detection the plain-int typed wrapper returns the type's default and the
outer call reports ok — both surfaces are legitimate, and which one wins
is a platform/timing race (consistently the fast path on Linux since the
transport extraction, still the slow path on macOS). Assert on the
stable part and teach the real contract: bad binds fail at call time;
methods that need caller-visible errors should return result.
* doctest(qml-ui): gate the Modules click on a wait_for
Right after the calculator round-trip the shell is still settling; on a
busy CI runner the Modules entry can take longer than the click action's
retry budget to materialize (flipped red on both platforms in one run,
green the previous hour, identical pins). Same pattern the spec already
uses for the post-launch wait.
* doctest(qml-ui): open Settings before clicking Modules
The Modules entry lives in the Settings left rail; clicking it cold
relied on incidental tree state (passed or failed depending on whether
the entry happened to be materialized). Mirror the basecamp doctests'
proven sequence: click Settings, wait for the view, then click Modules.
* tutorial: demonstrate the CallError out-param on bound interface calls
Generated typed wrappers now take an optional trailing
logos::CallError* — sumVia checks it and returns -1 when the inner call
fails (err.code == "object_unavailable" for a missing module), so the
bad-bind lesson no longer depends on which way the failure-timing race
falls. The doctest assert stays tolerant of the slow-transport
outer-timeout surface.
basecamp moved its modules view: the old top-level "Modules" sidebar entry
was renamed to "Package Manager", and the UI Modules / Core Modules tabs now
live under Settings → Modules. The Part 2 UI doc-test still clicked a
top-level "Modules", which no longer exists, so the step failed with:
click("Modules"): No element found with text 'Modules'
Click "Settings" first (and wait for the Settings view to render), then the
now-nested "Modules" sub-tab — mirroring logos-basecamp's own
basecamp-modules doc-test. Prose and the generated outputs/ markdown updated
to "Settings → Modules → Core Modules".
Caught by the logos-workspace nightly doc-test run against the bumped
logos-basecamp commit.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Document + verify event introspection in the tutorials
Mirror the per-method documentation coverage for events. The
wrapping-c-library calc_module already emits a versionReady event; give
it a /// doc comment and assert the whole event pipeline end-to-end.
- wrapping-c-library: document the versionReady event; add a 'List
events' step asserting 'lm events' shows the signature + both
description lines; assert logoscore module-info's Events section.
- qml-ui-app: rename the basecamp ui_test driver call openMethods ->
openInterface and assert the event's description renders on the
Interface screen (basecamp-interface-docs.png).
- Regenerate both tutorial markdowns.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* rerun
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* demonstrate and validate method doc comments (wrapping-c-library)
Add /// doc comments to the calc module's methods and assert they surface
via `lm methods` (human + --json) and `logoscore module-info`. Corrects the
stale lm output (provider-path introspection lists only impl methods, not
eventResponse/initLogos). Regenerated the tutorial markdown.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* showcase multi-line doc comments in the calc module
factorial uses two /// lines and libVersion uses a /** ... */ block; both
join into a single-line description. Assertions and rendered output updated
to match the joined text.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* preserve multi-line doc comments in the calc module tutorial
factorial/libVersion/libVersionNotify now keep their line breaks in lm and
logoscore module-info output; assertions and rendered markdown updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* use consistent introspection terminology in the tutorial
Refer to "the module's method introspection" throughout instead of mixing the
internal getMethods()/getPluginMethods names. Addresses review feedback on #60.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* verify method docs on basecamp's Methods screen (Part 2 doctest)
Extends the Part 2 basecamp ui_test to open calc_module's Methods screen
(via CoreModulesView.openMethods) and assert each method's description
renders — including factorial's multi-line doc comment. Closes the GUI
surface of the per-method documentation feature in the automated doctest.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* rerun
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>