Skip to content

Split Emanote into focused Cabal packages#679

Draft
srid wants to merge 7 commits intomasterfrom
split-multi-package-layout
Draft

Split Emanote into focused Cabal packages#679
srid wants to merge 7 commits intomasterfrom
split-multi-package-layout

Conversation

@srid
Copy link
Copy Markdown
Owner

@srid srid commented Apr 27, 2026

Emanote is now split into focused internal Cabal packages for routes, sources, Pandoc support, model logic, and the app layer. This closes #600 by making the module boundaries enforceable at build time instead of relying on naming convention inside one large package.

The app package keeps the runtime concerns: Ema route encoders, concrete Pandoc renderers, Heist template state, Tailwind flags, process IDs, and the Stork engine/cache now live above the model package. The lower packages remain reusable building blocks, with tests moved to the packages that own the behavior they exercise.

The split is wired through Cabal and Nix with explicit cabal.project package entries and the flake Haskell root widened to include packages/. I verified the branch with nix develop -c cabal build all, nix develop -c cabal test all, and all three configured e2e modes: just e2e-live, just e2e-static, and just e2e-morph.

Closes #600.

Try it locally

nix run github:srid/emanote/split-multi-package-layout

Generated by /do on Codex (model gpt-5).

srid added 7 commits April 26, 2026 20:38
Remove the static file path payload from SiteRoute and let the app look up the serving path from the model.
Delegate note and static-file SiteRoute construction to the model resolver helper so conversion logic has a single owner.
Give route, pandoc, and model packages their own test suites and leave app tests for app-owned behavior.
@srid
Copy link
Copy Markdown
Owner Author

srid commented Apr 27, 2026

Structural Review Follow-up

Hickey findings fixed in this PR

Finding Disposition Follow-up
Static routes carried file payloads Fixed 3f2e7569 removes the static file path from ResourceRoute_StaticFile; the app resolves file paths from the model at render time.
Duplicate route constructors Fixed fa715828 routes app helpers through Emanote.Model.Link.Resolve.resourceSiteRoute.
Lower-package tests lived in the app package Fixed e2d133ba moves route, Pandoc, and model specs into the packages that own them.
Model package owned app runtime state Fixed 1512b732 introduces Emanote.Site.Model and trims emanote-model back to notebook/model data.

Lowy findings fixed in this PR

Finding Disposition Follow-up
Model owned app runtime volatility Fixed 1512b732 moves route prism, renderers, template state, Tailwind flag, UUID, live-server flag, and Stork cache out of emanote-model.
Stork engine lived in the model package Fixed 98175c40 moves Stork build/cache modules to Emanote.Stork in the app package.
Route/source/Pandoc split question No-op The package split already keeps generic route/source/Pandoc code in lower packages while app-specific renderers stay in emanote.

Code-police follow-up

b4810d10 generalizes two Emanote.Site.Model readers that did not need the fully encoded app model.

@srid
Copy link
Copy Markdown
Owner Author

srid commented Apr 27, 2026

Evidence

No screenshot evidence was captured for this PR because the change is an internal package-boundary refactor with no visible UI surface.

Rendering paths were still exercised by the test suite:

  • nix develop -c cabal test all
  • just e2e-live: 22/22 scenarios passed
  • just e2e-static: 20 scenarios passed, with the 2 morph scenarios skipped by mode
  • just e2e-morph: 22/22 scenarios passed
  • vira ci: x86_64-linux and aarch64-darwin signoffs succeeded for b4810d10

@srid
Copy link
Copy Markdown
Owner Author

srid commented Apr 27, 2026

/do results

Step Status Duration Verification
sync 0s git fetch ok; forge=github; noGit=false
research 3m 46s Fetched issue #600 and mapped package/build blockers: cabal.project, nix projectRoot, SiteRoute.Type hashtag dependency, model SiteRoute.Class imports, and Stork URL rendering injection.
branch 0s Created feature branch split-multi-package-layout from origin/master.
implement 4m 20s Moved app package under packages/emanote, extracted route/source/pandoc/model packages, patched boundary imports, injected Stork URL rendering, and updated Cabal/Nix package discovery.
check 2m 27s Configured check ran as nix develop -c cabal build all because cabal is not on the ambient PATH; all packages and executable built successfully.
docs 53s Updated docs and changelog for packages/emanote default-layer paths and the new multi-package layout.
fmt 27s just fmt completed cleanly after cabal-fmt normalized the new package files.
commit 26s Created and pushed commit a780e5e (refactor: split emanote into packages) to origin/split-multi-package-layout.
hickey+lowy 27m 11s Applied all Hickey/Lowy findings in follow-up commits: simplified static routes, consolidated route construction, moved tests to owning packages, moved app runtime state out of emanote-model, and moved Stork engine ownership to the app package; nix develop -c cabal build all passed after the final fix.
police 2m 6s Code-police pass found one small elegance issue in Emanote.Site.Model readers being unnecessarily restricted to Model; fixed in b4810d1 and verified with nix develop -c cabal build all plus pre-commit.
test 2m 36s nix develop -c cabal test all passed all package unit tests; just e2e-live passed 22/22 scenarios; just e2e-static passed 20 scenarios with 2 morph scenarios skipped by mode; just e2e-morph passed 22/22 scenarios.
create-pr 42s Created draft PR #679 (#679) and posted structural review follow-up comment #679 (comment).
ci 4m 1s vira ci completed successfully, built the flake outputs for x86_64-linux and aarch64-darwin, and created GitHub signoffs vira/aarch64-darwin and vira/x86_64-linux for b4810d1.
evidence 11s Posted PR evidence comment #679 (comment) noting that no screenshot was needed for this internal package-boundary refactor and listing unit, e2e, and vira CI coverage.
done 16s All workflow steps succeeded; final results table is being generated from .do-results.json and posted to PR #679.
Total 51m 43s

Slowest step: hickey+lowy (27m 11s)

Optimization suggestions

  • The structural review pass dominated the run. For future package-boundary refactors, split the first pass into a smaller package move PR and then a runtime-boundary cleanup PR so Hickey/Lowy has less diff to evaluate at once.
  • CI was only 4m 1s, so reruns after comment-only or metadata-only follow-ups should use /do --from ci-only rather than replaying the full workflow.
  • The local test step was short relative to the review work. Keep the package unit tests colocated with their owning packages so future reviewers can validate boundary moves without re-reading the whole app test suite.

Workflow completed at 2026-04-27T01:17:39Z.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Split into multiple packages

1 participant