BXL indexing-correctness tests and realm-server node smoke suite - #5806
BXL indexing-correctness tests and realm-server node smoke suite#5806habdelra wants to merge 4 commits into
Conversation
Add a host integration suite for the indexing dimension of BXL computeds — that they land in the search doc in a shape the query engine matches and sorts on, and that they recompute when an edit invalidates the card — and a realm-server node smoke suite proving the package's raw-.ts sources and dynamic-import formula chunks load and evaluate under node's native type stripping. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6c6bf22f52
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - 'packages/base/**' | ||
| - 'packages/boxel-icons/**' | ||
| - 'packages/boxel-ui/**' | ||
| - 'packages/bxl/**' |
There was a problem hiding this comment.
Trigger the actual host-test workflow for BXL changes
Adding packages/bxl/** to this boxel filter does not run the new host integration suite: the actual host-test job lives in .github/workflows/ci-host.yaml, whose pull_request.paths list (lines 8–18) still omits packages/bxl/**. Consequently, a future BXL-only PR triggers the standalone BXL and realm-server suites but never executes bxl-indexing-test.gts, leaving the cross-package indexing regressions this commit intends to catch untested; add BXL to the CI Host workflow trigger as well.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
[Claude Code 🤖] Correct — the boxel output in ci.yaml only gates test-web-assets and the main-branch deploy; the host-test shards live in ci-host.yaml behind its own paths list. A BXL-only change would have run the bxl and realm-server suites and skipped the host indexing suite entirely.
packages/bxl/** added to ci-host.yaml's paths in 703ed32. Leaving the matrix filter alone: those e2e flows don't exercise BXL cards, and the only way a BXL change breaks them is by breaking the host build, which host-test already catches.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds coverage for BXL correctness at index-time (search doc shape + incremental recomputation) and ensures the @cardstack/bxl package runs under Node’s native TS type-stripping (including dynamic-imported formula chunks), closing gaps that browser-only suites can’t catch.
Changes:
- Add a new host integration suite that asserts BXL computeds are query-matchable/sortable via the indexed search doc and that dependent cards reindex correctly across direct edits, linked edits, module edits, and “missing inputs” scenarios.
- Add a new realm-server Node smoke suite that imports
@cardstack/bxland exercises evaluate/compile + lazy extension loading (dynamic import + fold-into-defaults). - Wire up supporting config: add
@cardstack/bxlto realm-server devDependencies, add ES2022 libs to realm-server TS config, and expand CI path filters so host/realm-server suites run on BXL-only changes.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Records the workspace link for @cardstack/bxl in the realm-server importer. |
| packages/realm-server/tsconfig.json | Adds explicit TS lib config including ES2022 to match BXL’s runtime/library usage. |
| packages/realm-server/tests/index.ts | Registers the new bxl-node-smoke-test in the realm-server test manifest. |
| packages/realm-server/tests/bxl-node-smoke-test.ts | New Node smoke tests for BXL import/evaluate/compile and dynamic formula extension loading. |
| packages/realm-server/package.json | Adds @cardstack/bxl as a devDependency for the new test suite. |
| packages/host/tests/integration/bxl-indexing-test.gts | New host integration suite focused on index-time correctness and incremental reindex behavior. |
| packages/host/tests/helpers/cards/bxl-tracking.ts | Exports bxlTrackingPol100Doc factory to support multiple convergence-triggering writes with non-identical content. |
| .github/workflows/ci.yaml | Expands change filters to include packages/bxl/** for relevant CI suites. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Preview deployments |
A blank or zero divisor yields null inside the jq engine's own null-tolerant arithmetic; only a function that raises an Excel sentinel throws, and only that path reaches the factory's catch. Assert both, and describe each by the mechanism that produces it. Name the invariant behind the staleness assertions, pair the superseded-value check with its positive counterpart, and take the revisit nonce off the caller. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
BXL's
deriveprofile runs at write/index time, so the search doc — not therendered card — is where a
computeViaexpression's correctness actuallylands. It is what queries filter and sort on, and it is rebuilt from scratch
every time an edit invalidates the card. The existing BXL host suites read
search docs, but they read them to pin what a formula returns; nothing
covered when a computed gets recomputed, or whether the value the indexer
wrote is in a shape the query engine can match on at all.
The other half of the gap is node. BXL is meant to be isomorphic, but until
now every test ran in the browser through Vite. The package ships raw
.tswith
.tsimport specifiers and pulls its heavy formula families in throughdynamic import, so node runs it under native type stripping with no bundler
to rewrite anything — a specifier the stripper can't follow, or a chunk only a
bundler could resolve, would fail there and nowhere else.
Host — indexing correctness
packages/host/tests/integration/bxl-indexing-test.gtsreuses the sharedtracking-realm fixture and covers two things the value-level suites don't:
The search doc the query engine sees. BXL computeds are matched by
equality and by range (so they indexed with their declared types), matched on
the nested paths of
{ as: FieldDef }materializations, and sorted on.Incremental reindex. An edit to a card's own input recomputes its
computeds and evicts the superseded value from the index; an edit to a linked
card recomputes the cards that traverse to it, one hop and two; an edit to the
formula in the card module recomputes every instance, not just the one in
hand; and an edit that strips a card's inputs still yields a clean
instanceentry rather than an
instance-error, with the Excel sentinels clipped tonull and the still-valid computeds intact.
Aggregations over the query-backed
claimsinverse are eventually consistent,and the tests pin that contract as it is: the stored edge runs claim → policy,
so writing a claim invalidates the claim, and the policy keeps the aggregate
from its last visit until it is visited again. That mirrors the first-pass
convergence the fixture already documents. Two tests exercise it — a claim
edit, and a claim joining then leaving the realm — asserting both the
pre-convergence and post-convergence states.
Realm-server — node smoke suite
packages/realm-server/tests/bxl-node-smoke-test.ts, registered inALL_TEST_FILES, imports@cardstack/bxlunder node and exercises evaluate(readable BXL and canonical jq), compile, and a lazy formula chunk — both the
async auto-load that performs the dynamic import and the explicit fold-into-
defaults step that lets a synchronous
computeViareach the familyafterwards. Cards can't run in node, so this is deliberately a smoke suite
over plain JS objects; the expressions are the ones the host's BXL card
fixtures compute, asserted to the same answers, so a divergence between the
two environments shows up as a number that stops matching.
Supporting changes
@cardstack/bxlbecomes a realm-server devDependency, and realm-server'stsconfig gains an explicit
libof ES2022 — BXL's sources use ES2022library APIs, and realm-server runs on node ≥ 24. The host already does the
same thing (ES2022 lib over an es2020 target).
boxelandrealm-serverchange filters inci.yaml, and thepathslist in
ci-host.yaml, now includepackages/bxl/**. The host suite isgated by
ci-host.yaml, not byci.yaml'sboxeloutput, so without thatthird one a BXL-only change would never have run the new indexing suite.
Two consequences worth naming: the
boxeloutput also gates themain-branch staging deploy, so a bxl-only merge to main now deploys where
before it did not — correct, since the host has bundled BXL since the
package landed, but it is a deploy-behavior change riding in a test PR. And
a bxl-only change now fires the full realm-server job to run one
dependency-free unit file. The
matrixfilter is deliberately left alone:those Playwright flows don't exercise BXL cards, and the only way a BXL
change breaks them is by breaking the host build, which
host-testalreadycatches.
bxlTrackingPol100Doc. A re-write of byte-identical content is skipped bythe realm, so a test that needs more than one convergence visit has to vary
the document.
One side effect of the devDependency: realm-server's
lint:typesnowtypechecks the whole reachable
packages/bxl/srcgraph, duplicating thesignal from bxl's own
lint:typesand adding time to the realm-server lintjob.
Testing
four suites green together.
pnpm lint:typesclean in both packages.