Skip to content

Move query planning from decision service to LSP, delete jl4-decision…#883

Merged
serrynaimo merged 19 commits intomainfrom
thomasgorissen/query-plan-via-lsp
Apr 10, 2026
Merged

Move query planning from decision service to LSP, delete jl4-decision…#883
serrynaimo merged 19 commits intomainfrom
thomasgorissen/query-plan-via-lsp

Conversation

@serrynaimo
Copy link
Copy Markdown
Collaborator

…-service

Query planning (elicitation ordering in the ladder visualizer) now runs via the LSP's l4/queryPlan custom request instead of requiring a running jl4-decision-service HTTP server. This works in both WebSocket and WASM modes — WASM gains query planning for the first time.

Key changes:

  • Add l4/queryPlan custom LSP request (CustomProtocol.hs, Handlers.hs)
  • Add WASM FFI export l4_query_plan (QueryPlanWasm.hs in jl4-wasm)
  • Replace decision service HTTP calls with LSP requests in jl4-web and VS Code extension
  • Delete jl4-decision-service entirely (superseded by jl4-service + LSP)
  • Unify VizExpr types: jl4-core is now the single source of truth, jl4-lsp re-exports and adds LSP conversion helpers
  • Drop Autodocodec from jl4-lsp (plain Aeson for VizExpr serialization)
  • Deduplicate InputRef, generateAtomId, vizExprToBoolExpr across packages
  • Remove dead QueryAsk.schema field from jl4-service
  • Remove @repo/vscode-webview-rpc package (empty after migration)
  • Remove jl4.decisionServiceUrl VS Code setting
  • Add 27 query plan unit tests (QueryPlanSpec.hs) covering both jl4-service and LSP computation paths with agreement verification

Thomas Gorissen and others added 19 commits April 9, 2026 11:51
…-service

Query planning (elicitation ordering in the ladder visualizer) now runs
via the LSP's l4/queryPlan custom request instead of requiring a running
jl4-decision-service HTTP server. This works in both WebSocket and WASM
modes — WASM gains query planning for the first time.

Key changes:
- Add l4/queryPlan custom LSP request (CustomProtocol.hs, Handlers.hs)
- Add WASM FFI export l4_query_plan (QueryPlanWasm.hs in jl4-wasm)
- Replace decision service HTTP calls with LSP requests in jl4-web and
  VS Code extension
- Delete jl4-decision-service entirely (superseded by jl4-service + LSP)
- Unify VizExpr types: jl4-core is now the single source of truth,
  jl4-lsp re-exports and adds LSP conversion helpers
- Drop Autodocodec from jl4-lsp (plain Aeson for VizExpr serialization)
- Deduplicate InputRef, generateAtomId, vizExprToBoolExpr across packages
- Remove dead QueryAsk.schema field from jl4-service
- Remove @repo/vscode-webview-rpc package (empty after migration)
- Remove jl4.decisionServiceUrl VS Code setting
- Add 27 query plan unit tests (QueryPlanSpec.hs) covering both
  jl4-service and LSP computation paths with agreement verification
- jl4-query-plan: switch to L4.Crypto.UUID5 from jl4-core instead of the
  uuid package, which transitively pulled in entropy and network-info
  (require netdb.h, not available in wasm32-wasi)
- decision-service-types: revert ladder field to non-optional in
  QueryPlanResponse — the wizard still uses jl4-decision-service's HTTP
  API which always returns ladder
QueryPlanWasm.hs: import CachedDecisionQuery(..) and InputRef(..)
explicitly so the field names are in scope for record construction.
With NoFieldSelectors enabled in jl4-query-plan, qualified imports
alone don't bring field names into scope; they need to be imported
unqualified via the constructor's record list. Also enable
OverloadedRecordDot pragma which is needed for nested field access.

wasm-bridge.ts: add public queryPlan() method instead of accessing
the private exports field from outside the class.

wasm-message-transports.ts: use the new bridge.queryPlan() method.
Required for the inline string literals used in JSON error responses
when constructing Aeson.object values.
The package was deleted but the nix build scripts for jl4-web and
l4-wizard still tried to pushd into the directory, causing the build
to fail with 'No such file or directory'.
The wizard was built against jl4-decision-service's flat function-keyed
HTTP API, which we deleted. Porting it to jl4-service would require
adapting to the deployment-prefixed URL structure and rendering DOT
client-side. Removing instead since it's not actively used.

- Delete ts-apps/l4-wizard/ entirely
- Delete ts-shared/decision-service-types/ (only the wizard used it)
- Remove wizard button and handleOpenWizard from jl4-web
- Remove VITE_WIZARD_URL env var, app.d.ts entry, .env files
- Remove nix/l4-wizard/, references in nix/configuration.nix and
  nix/jl4-web/{configuration,package}.nix
- Clean up dev-start.sh and dev-healthcheck.sh (also drop dead
  jl4-decision-service references)
After deleting the package, sweep through the rest of the repo:

Deleted:
- Dockerfile.jl4-decision-service
- jl4/experiments/query-planner-tests/{TEST-RESULTS,TESTING-WORKFLOW,
  TEST-SCENARIOS,UX-REQUIREMENTS,NON-MONOTONICITY,BACKTICK-BINDING-ISSUE}.md
- jl4/experiments/query-planner-tests/{run-all-tests,start-decision-service,
  test-api}.sh

Cleaned up:
- docker-compose.{yml,dev.yml}: remove jl4-decision-service service
- Dockerfile.jl4-websessions: drop decision-service URL from CMD
- jl4-dev, dev-start.sh, dev-healthcheck.sh: remove decision service
  references and ports
- jl4-websessions: remove pushToDecisionService and HandlerEnv.{httpManager,
  decisionServiceUrl}; drop http-client dep; update test
- jl4-websessions/README.md: rewrite to describe current SQLite-only behavior
- jl4-service/README.md: replace deprecation comparison table with feature
  list
- nix/jl4-service/configuration.nix: drop comparison comment
- jl4/app/Main.hs, jl4-core/src/L4/TracePolicy.hs: update code comments
- AGENTS.md: drop deprecated row from package table
- doc/courses/advanced/module-a4-production.md: rewrite REST API example
  for jl4-service deployment-based API
- jl4/examples/{implicit-assume-test,ok/assume-as-given}.l4: rename
  comments to refer to jl4-service; update golden file
- cabal-wasm.project: update comment
- query-planner-tests/README.md: rewrite to point at QueryPlanSpec.hs
Follow-up to commits 4211b36 (delete l4-wizard + decision-service-types)
and 987df14 (purge jl4-decision-service refs). Cleans up the remaining
stragglers:

- README.md, doc/courses/README.md: fix Module A4 nav labels that still
  called it "Decision Service APIs" / "Decision Services". The module was
  retitled to "Production Patterns" but the nav index wasn't updated.
- ts-apps/jl4-web/.env.wasm: drop the trailing dangling "# Decision
  Service URL" section header (had no matching VITE_* var anyway).
- ts-shared/l4-ladder-visualizer/src/lib/index.ts: remove stale
  "decision-service query-plan helpers" comment; query-plan now lives in
  jl4-lsp.
- specs/done/: delete 11 completed specs whose subject code
  (jl4-decision-service or l4-wizard) no longer exists — they document
  work on deleted packages and only serve to confuse future greps.
Updates actions/checkout, actions/setup-node, and actions/cache
(including cache/restore and cache/save) from v4 to v5 to address
the Node.js 20 deprecation warning on GitHub Actions runners.
The Haskell build-artifact cache save step was unconditionally running
on success, which failed with "another job may be creating this cache"
whenever the primary key already existed (i.e. when restore produced an
exact hit). Guard the save on cache-hit != 'true' and reuse the
primary key from the restore step, matching the pattern used for the
deps cache.
Addresses esbuild dev-server request hijack (GHSA-67mh-4wv8-2f99) by
bumping the direct esbuild devDep in vscode, webview, and
l4-ladder-visualizer. Aligns engines.node with the Node 24 workflows
landed earlier on this branch and pins the matching npm@11.11.0.

Remaining npm audit findings (cookie, diff, picomatch, serialize-javascript,
mocha) are all in dev-only or adapter-static paths with no runtime
attack surface and no non-breaking fix available upstream.
The npm 11 install in the previous commit stripped resolved/integrity
fields and collapsed optional platform-specific deps down to the mac
variant only. This broke CI:
- nix import-npm-lock requires `.resolved` on every entry
- npm bug #4828 leaves Linux runners unable to find @rollup/rollup-linux-x64-gnu
  because only @rollup/rollup-darwin-arm64 survived the regeneration

Re-seeded the lockfile from the pre-regen state and re-applied the
esbuild bump on top, preserving all 25 rollup platform entries, the
full set of @esbuild/@parcel/@tailwindcss/vsce/lightningcss variants,
and resolved fields throughout.
@serrynaimo serrynaimo merged commit a91fafc into main Apr 10, 2026
5 checks passed
@serrynaimo serrynaimo deleted the thomasgorissen/query-plan-via-lsp branch April 10, 2026 15:16
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.

1 participant