Every #include line in README.md names a header that does not exist
include/morph/ has no flat headers — everything lives under a subsystem
directory (core/, forms/, util/, journal/, session/, offline/,
qt/, net/, render/). The only file directly under include/morph/ is
version.hpp.
README.md's copy-pasteable snippets use the flat spelling throughout:
README.md:71:#include <morph/registry.hpp>
README.md:88:#include <morph/bridge.hpp>
README.md:89:#include <morph/backend.hpp>
README.md:90:#include <morph/executor.hpp>
README.md:163:#include <morph/registry.hpp>
README.md:290:#include <morph/forms.hpp> // pulls in quantity.hpp + rational.hpp
None of those resolve. The correct paths are morph/core/registry.hpp,
morph/core/bridge.hpp, morph/core/backend.hpp, morph/core/executor.hpp
and morph/forms/forms.hpp.
Verification status
Reproduced on 93a6168, macOS 15.6 (arm64), Homebrew clang 22.1.8.
The README's "The main idea" block, copied verbatim into a file and compiled
with nothing but morph's own include directory and Glaze on the path:
$ clang++ -std=c++23 -I<repo>/include -I<glaze>/include -fsyntax-only readme_snippet.cpp
readme_snippet.cpp:2:10: fatal error: 'morph/registry.hpp' file not found
2 | #include <morph/registry.hpp>
| ^~~~~~~~~~~~~~~~~~~~
1 error generated.
It fails on line one — before reaching anything the snippet is trying to
teach.
That the corrected paths work is confirmed by the same program compiling and
running once the includes are fixed (this is what
examples/concepts/getting_started.cpp and every ladder rung already use).
Not confined to the README
docs/ARCHITECTURE.md:409:#include <morph/registry.hpp>
docs/spec/core/registry.md:572: class is declared in `morph/bridge.hpp` in namespace `morph::bridge` …
docs/spec/core/registry.md:672: must include `<morph/bridge.hpp>` (directly or transitively) because …
docs/spec/core/registry.md:1023: `ActionExecuteRegistry` … (declared in `<morph/bridge.hpp>`, not `registry.hpp`)
docs/spec/core/registry.md:1024: Explains the hard `#include <morph/bridge.hpp>` requirement
docs/spec/util/quantity_type.md:865:#include <morph/quantity.hpp>
examples/forms/README.md:99: see `BridgeHandler::executeJson` in `morph/bridge.hpp`
and in the code's own documentation — include/morph/core/registry.hpp's
BRIDGE_REGISTER_ACTION doc comment states the hard requirement as
<morph/bridge.hpp>, and include/morph/detail/quantity_equation.hpp:8 refers
to morph/quantity.hpp.
Note docs/spec/core/registry.md:672 is the authoritative statement of a
link-time hard requirement — "every translation unit invoking
BRIDGE_REGISTER_ACTION must include <morph/bridge.hpp>". A reader who
follows it literally gets a file-not-found; a reader who guesses core/
gets it right. The requirement itself is correct and load-bearing; only the
path is wrong.
README.md's "Subsystems" table has the same shorthand (executor.hpp,
strand.hpp, completion.hpp, registry.hpp, model.hpp, model_key.hpp,
backend.hpp, remote.hpp, bridge.hpp, wire.hpp, session.hpp,
journal.hpp, rational.hpp, quantity.hpp, datetime.hpp, forms.hpp,
choice.hpp). In a table that is arguably shorthand rather than an error, but
it is the same drift and it is what makes the snippets look plausible.
Not verified: whether the flat layout ever existed and this is post-move
drift, or whether the README always described an intended layout. Either way
the current tree is the one a reader compiles against.
Impact
This is the very first thing a newcomer does — copy the README's headline
example — and it cannot compile. Nothing in CI notices, because every
first-party consumer (examples/**, tests/**) uses the real paths; the
broken spelling exists only in prose.
Found while writing docs/GETTING-STARTED.md (#170), whose section 7 has to
restate the BRIDGE_REGISTER_ACTION include requirement and could not simply
quote the spec's wording.
What would change the verdict
Close this when every #include <morph/...> in README.md,
docs/ARCHITECTURE.md, docs/spec/** and include/morph/** doc comments
names a path that exists on disk. A cheap guard worth adding in the same
change: a lint that extracts every morph/…\.hpp mentioned in tracked
markdown and header comments and asserts the file exists — the same shape as
scripts/check_spec_citations.sh, which already scans this prose for a
different class of drift.
Every
#includeline in README.md names a header that does not existinclude/morph/has no flat headers — everything lives under a subsystemdirectory (
core/,forms/,util/,journal/,session/,offline/,qt/,net/,render/). The only file directly underinclude/morph/isversion.hpp.README.md's copy-pasteable snippets use the flat spelling throughout:
None of those resolve. The correct paths are
morph/core/registry.hpp,morph/core/bridge.hpp,morph/core/backend.hpp,morph/core/executor.hppand
morph/forms/forms.hpp.Verification status
Reproduced on
93a6168, macOS 15.6 (arm64), Homebrew clang 22.1.8.The README's "The main idea" block, copied verbatim into a file and compiled
with nothing but morph's own include directory and Glaze on the path:
It fails on line one — before reaching anything the snippet is trying to
teach.
That the corrected paths work is confirmed by the same program compiling and
running once the includes are fixed (this is what
examples/concepts/getting_started.cppand every ladder rung already use).Not confined to the README
and in the code's own documentation —
include/morph/core/registry.hpp'sBRIDGE_REGISTER_ACTIONdoc comment states the hard requirement as<morph/bridge.hpp>, andinclude/morph/detail/quantity_equation.hpp:8refersto
morph/quantity.hpp.Note
docs/spec/core/registry.md:672is the authoritative statement of alink-time hard requirement — "every translation unit invoking
BRIDGE_REGISTER_ACTIONmust include<morph/bridge.hpp>". A reader whofollows it literally gets a file-not-found; a reader who guesses
core/gets it right. The requirement itself is correct and load-bearing; only the
path is wrong.
README.md's "Subsystems" table has the same shorthand (
executor.hpp,strand.hpp,completion.hpp,registry.hpp,model.hpp,model_key.hpp,backend.hpp,remote.hpp,bridge.hpp,wire.hpp,session.hpp,journal.hpp,rational.hpp,quantity.hpp,datetime.hpp,forms.hpp,choice.hpp). In a table that is arguably shorthand rather than an error, butit is the same drift and it is what makes the snippets look plausible.
Not verified: whether the flat layout ever existed and this is post-move
drift, or whether the README always described an intended layout. Either way
the current tree is the one a reader compiles against.
Impact
This is the very first thing a newcomer does — copy the README's headline
example — and it cannot compile. Nothing in CI notices, because every
first-party consumer (
examples/**,tests/**) uses the real paths; thebroken spelling exists only in prose.
Found while writing
docs/GETTING-STARTED.md(#170), whose section 7 has torestate the
BRIDGE_REGISTER_ACTIONinclude requirement and could not simplyquote the spec's wording.
What would change the verdict
Close this when every
#include <morph/...>inREADME.md,docs/ARCHITECTURE.md,docs/spec/**andinclude/morph/**doc commentsnames a path that exists on disk. A cheap guard worth adding in the same
change: a lint that extracts every
morph/…\.hppmentioned in trackedmarkdown and header comments and asserts the file exists — the same shape as
scripts/check_spec_citations.sh, which already scans this prose for adifferent class of drift.