Relationships
#600 Local source-loading should discover a report co-located with its model in a paths.base:manifest extension
Opened by stateless · 6/9/2026· Shipped 6/9/2026
Problem
A report is, in MVC terms, the view for a model — it naturally belongs in the
same extension as the model it summarizes. Publishing supports that (the manifest
reports: field bundles the report alongside the model). Local source
development does not.
In a self-contained extension using paths.base: manifest — manifest, model,
README, LICENSE all in one directory under extensions/models/<name>/ — a report
listed in reports: and placed in that same directory:
- bundles and loads correctly once pulled, but
- is NOT discovered during local source development: the model loads (it
matches the
extensions/models/**discovery glob) while the co-located report does not (report discovery only globsextensions/reports/**).
So the extension loads partially from source (model yes, report no) even though
it loads fully when pulled — a dev/prod parity gap. And the manifest can't
point at extensions/reports/ instead, because manifest paths reject ..
("Path must be relative and must not contain '..' components").
Reproduce
extensions/models/myext/withmanifest.yaml(paths.base: manifest), a model.ts, and a report.tslisted underreports:.swamp doctor extensions --verbose— the model registers; the report does not (no report row for it).- A method whose definition has
reports.require: [<that report>]does not run it locally. swamp extension source add <that dir>does not help — a path already covered by the repo-root layout is ignored to prevent double-loading.
(Confirmed by dropping .swamp/_extension_catalog.db and rescanning — the report
never registers from the model dir.)
Proposed
Local source-loading should honor a discovered manifest's declared files — load
all declared components (models, reports, vaults, drivers, …) from the
manifest's own directory — so source/dev loading matches the published bundle.
(Alternatively, the per-type discovery globs could include
paths.base: manifest extension subdirectories.)
Impact / workaround
Today, a bundled report can't be exercised from source. The workarounds are to
keep the report in extensions/reports/ (separated from the extension it ships
in) or publish it as a standalone companion extension — both of which defeat the
"view ships with its model" layout the manifest otherwise supports.
Shipped
Click a lifecycle step above to view its details.
stateless commented 6/9/2026, 9:54:04 AM
Scope note: this isn't report-specific — the root cause is that local
source-loading discovers each extension type from its own directory
(extensions/reports/, top-level workflows/, extensions/vaults/, …), so
any non-model file co-located in a paths.base: manifest extension dir is
missed locally, even though it's declared in the manifest and bundles correctly
when pulled. It applies to reports, workflows, vaults, and drivers, not just
reports.
One caveat worth confirming: the publishing path-resolution docs give
workflows under manifest mode a "manifest dir first, then repo-root
fallback" resolution that reports don't have — so workflows may already behave
differently for discovery. Worth verifying as part of the fix.
Suggested framing: local source-loading should honor a discovered manifest's declared files across all types (load every declared component from the manifest dir), so source/dev loading matches the published bundle uniformly.
stack72 commented 6/9/2026, 7:58:34 PM
Thanks @stateless for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.