Application ladder: rungs 0-3 (pastebin, bookmarks, polls) + shared infrastructure - #41
Open
Yaraslaut wants to merge 5 commits into
Open
Application ladder: rungs 0-3 (pastebin, bookmarks, polls) + shared infrastructure#41Yaraslaut wants to merge 5 commits into
Yaraslaut wants to merge 5 commits into
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Yaraslaut
commented
Aug 11, 2026
Yaraslaut
pushed a commit
that referenced
this pull request
Aug 11, 2026
…r-wide Scopes DataMapperPool adoption, pastebin's animal-name-id -> SqlGuid conversion, plain std::string -> Lightweight strong string types, and int64 epoch-ms -> SqlDateTime across bank/bookmarks/pastebin/polls. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yaraslaut
pushed a commit
that referenced
this pull request
Aug 13, 2026
…r-wide Scopes DataMapperPool adoption, pastebin's animal-name-id -> SqlGuid conversion, plain std::string -> Lightweight strong string types, and int64 epoch-ms -> SqlDateTime across bank/bookmarks/pastebin/polls. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yaraslaut
force-pushed
the
application-ladder
branch
from
August 13, 2026 11:20
2101867 to
4722098
Compare
The application ladder -- a planned sequence of stateful example apps of gradually increasing complexity, each stressing a distinct set of morph subsystems (examples/LADDER.md). This commit carries rung 0: everything the rungs themselves share, not any one rung's own model/DTO/GUI code. - MORPH_BUILD_LADDER build wiring, morph_add_rung() per-rung scaffolding (examples/CMakeLists.txt, cmake/morph_add_rung.cmake). - Shared testkit (examples/common/testkit/): pump.hpp, db_fixture.hpp/ db_fault_fixture.hpp/db_busy_fixture.hpp, backend_rig.hpp, fault_proxy, strand_interleaver.hpp -- the fixtures every rung's own tests build on. - Shared presenter architecture (examples/common/gui/): Presenter, AppContext, event_poller.hpp/.cpp, plus the WASM-remote spike (examples/common/wasm_spike/) proving QtWebSocketBackend works from Emscripten. - Framework changes the rungs surfaced, landing in include/morph/core/ rather than any rung's own tree: RemoteServer's same-model execute reordering, fixed with a per-model ticket gate (tests/test_remote_execute_ordering.cpp). - CI: a path-filtered ladder-tests job, coverage measurement extended to the ladder's hand-written code, the WASM build+gate leg (.github/workflows/wasm-ladder.yml), and every standing CI fix found building the rungs (an MSVC /bigobj gap, a morph_add_rung() Emscripten check, several Clang -Weverything diagnostics the WASM leg's older bundled Clang surfaces that Linux/Windows Clang never did). - docs/findings/001-036: each a minimal failing test or a spec-cited impossibility, opened and closed as the rungs' own construction surfaced or resolved them. - Planning docs (docs/superpowers/plans/) and a design doc scoping a follow-up storage-types pass from PR review comments, not yet implemented. - README-only stubs for five not-yet-built future rungs (crm, forge, kanban, ledger, lims). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Animal-name-keyed pastes with burn-after-read, expiry, and edit conflict detection -- the first rung exercised end-to-end (server, desktop GUI, WASM client). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Multi-user bookmarks with tags, bulk edit, Netscape-format import, a cross-user shared feed, and session-based auth. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Multi-participant polling with vote/comment history, undo, finalization, and a Zulip-pattern event log (GetEventsSince) -- the first rung to exercise the framework's async keyed/shared-model attach path, which drove the core framework additions in the shared-infrastructure commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yaraslaut
force-pushed
the
application-ladder
branch
from
August 13, 2026 11:27
4722098 to
46cda21
Compare
…ts, remove settled findings Goes through every finding filed against rung 0-3 (36 files total) and either migrates the ladder's own code onto the public seam that closes it, corrects every stale in-code comment/README passage that still described a closed gap as open, or removes the finding file once its content is durably captured elsewhere (a spec section, a GitHub issue, or the fix's own code comments) -- never leaving a bare historical record behind. Code migrations (findings 019, 024): - Testkit reach-ins onto public seams: Completion<T>::makeSettleable()/ Promise replaces direct CompletionState<T> construction (test_pump.cpp); BridgeHandler::isBound()/whenBound() replaces manual HandlerBinding construction + registerHandler + currentId polling (test_wasm_registration_path_native.cpp, wasm_spike/main_wasm.cpp); QtWebSocketBackend(url, tls, cfg) replaces the defaultDispatcher()/defaultRegistry() padding five call sites no longer need (app_context.cpp, test_fault_proxy.cpp, and the above). StrandExecutor/ModelId reach-in (strand_interleaver.hpp) is kept on purpose, documented as testkit-layer-by-design: those tests prove StrandExecutor's own ordering guarantee and a stand-in would prove nothing. - Presenter::bound()/trackBound() (examples/common/gui/presenter.hpp), backed by Bridge::whenBound(), gates every rung's bootstrap dispatch (PastePresenter/BookmarkPresenter/TagPresenter/SharedFeedPresenter and their QML bridges/Main.qml/BookmarkListView.qml) instead of a 150ms polling Timer. Guarded with QPointer<Presenter>, not a bare `this` capture -- whenBound()'s Completion resolves through the executor asynchronously even in Local mode, so a short-lived presenter torn down before that post runs would otherwise be dereferenced after destruction (caught via a genuine SIGSEGV repro under cdb during this work, in a presenter destroyed between test cases). PollPresenter is untouched: nothing in polls' QML dispatches on Component.onCompleted, so that rung never hits the window this closes. - Along the way, verified and fixed bookmarks' own tags field (CreateBookmark::tags/EditBookmark::tags, a JSON array of strings) now renders and submits correctly through DynamicForm's array-field control -- the README's "tagging is not reachable from the GUI at all" claim was stale; neither Main.qml nor BookmarkListView.qml special-cases the field. Findings removed after independent re-verification against current source (not their own disposition: labels, which are known to drift): 003, 005-009, 011-014, 019-021, 023-026, 028-034 (framework fixes confirmed landed, each with its own commit/regression test), 001, 002, 004 (rung-0 framework prerequisites, all confirmed shipped), 017 (its queueing behavior was already fully documented in docs/spec/core/backend.md -- the finding file was pure redundant history), 018 (folded directly into examples/TESTING.md's testkit section and examples/IMPLEMENTATION.md rule 5, since it's a genuine, still-current limitation that belongs in the governing docs, not a separate finding file), 035 (RemoteServer execute-ordering gate; its full design history, including the reverted first attempt, is now condensed into remote.hpp's own comment rather than a separate file). Two genuine, still-open technical gaps were filed as GitHub issues instead of finding files, since they're real work items someone should eventually pick up: - 022 (sqliteodbc's UPDATE...RETURNING reports success but SQLFetch throws SQLSTATE 24000) -- a third-party driver bug, filed as LASTRADA-Software/Lightweight#545 with the full reproducer; cross-linked with morph's own tracking issue (#58, already existed). - 036 (BookmarkModel::execute(GetChangesSince)'s millisecond-resolution cursor can miss a same-millisecond write) -- already tracked as morph#43; added the GetEventsSince id-cursor precedent and remaining design-work detail from the finding file as a follow-up comment before removing it. Left untouched, correctly: 010 (forms sum-type gap), 015 (reconcileDeclaredPrecision spec/code agreement, already verified matching), 016 (FileOfflineQueue linear-scan dedup) -- all three `documented-limitation`, independently re-checked against docs/spec/forms/forms.md and docs/spec/offline/offline.md, both specs already stating the identical content verbatim. And 022/036's replacement issues are new work items, not closed findings -- left open on GitHub for whoever picks them up next. Verified throughout: full core suite (morph_tests: 9774 assertions, morph_qt_tests: 496 assertions) plus every ladder rung (ladder_common/pastebin/bookmarks/polls_tests: 2423 assertions total), all green. The only non-comment production-code changes are the Presenter::bound()/whenBound() migration and its QPointer lifetime fix; everything else is documentation, test-comment, or finding-file churn.
Yaraslaut
force-pushed
the
application-ladder
branch
from
August 13, 2026 14:23
812834a to
cf68403
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The application ladder — a planned sequence of stateful example apps of gradually increasing
complexity, each stressing a distinct set of morph subsystems. This PR now carries rung 0
(shared infrastructure) through rung 3 (polls), not just rung 0 as originally scoped:
MORPH_BUILD_LADDERbuild wiring,morph_add_rung()per-rung scaffolding, the shared testkit (
pump.hpp,db_fixture.hpp/db_fault_fixture.hpp,backend_rig.hpp,fault_proxy,strand_interleaver.hpp), and the shared presenterarchitecture (
Presenter,AppContext, the WASM-remote spike provingQtWebSocketBackendworks from Emscripten).
conflict detection; the first rung exercised end-to-end (server, desktop GUI, WASM client).
a cross-user shared feed, and session-based auth.
and a Zulip-pattern event log (
GetEventsSince) — the first rung to exercise the framework'sasync keyed/shared-model attach path, which drove core framework additions (see below).
Framework changes surfaced by building the rungs (not rung-scoped, land in
include/morph/core/):Bridge::setExecuteDeadline).two exception-safety gaps in
switchBackend(found while building polls' shared poll state).TimeoutSchedulerfor single-threaded WASM.Findings:
docs/findings/001-033— each a minimal failing test or a spec-citedimpossibility, opened and closed as the rungs' own construction surfaced or resolved them
(e.g. 017's async-registration-before-connect bug, 030's attachModel staleness, 031's
DynamicFormarray-field gap, 033's poisoned-attach reproduction).CI: a path-filtered
ladder-testsjob, coverage measurement extended to the ladder'shand-written code, the GUI/WASM build+gate legs, and (this session) a full pass fixing every
standing CI failure on the branch — a
bridge.hppunused-capture warning, an MSVC/bigobjgap, a
morph_add_rung()check that unconditionally required a testkit target Emscriptencorrectly never builds, and half a dozen Clang
-Weverythingdiagnostics the WASM leg'solder bundled Clang surfaces that the Linux/Windows Clang never did — plus a design doc
(
docs/superpowers/specs/2026-08-11-strong-storage-types-design.md) scoping a follow-up pass(
DataMapperPooladoption, GUID ids, Lightweight strong string/timestamp types) from PR reviewcomments, not yet implemented.
Testing
shared testkit fixtures — no mocked persistence anywhere.
examples/TESTING.mdrequires,plus full presenter/bridge coverage in C++.
ladder_pastebin_tests,ladder_bookmarks_tests,ladder_polls_tests,ladder_common_testsall rebuild clean and pass against a real SQLiteODBC backend (one known pre-existing Windows temp-file-lock flake in bookmarks'
test_app.cpp,unrelated to any change in this PR).
WASM ladder gatehas never passedon this branch and is being brought up incrementally, commit by commit, as each new layer of
breakage surfaces.
🤖 Generated with Claude Code