The existing 380-test backend suite runs entirely against the in-memory
datastore provider, which treats every partition-key value as equivalent.
This hid one entire class of bug — partition-key mismatches — until
production. D7 closes that gap.
Implementation:
- backend/src/test-helpers.ts adds useCosmosDatastore() that swaps the
active provider for CosmosDatastoreProvider using COSMOS_ENDPOINT /
COSMOS_KEY / COSMOS_DATABASE. Throws synchronously when env is missing
so a misconfigured run fails loudly instead of silently falling back
to in-memory.
- backend/vitest.config.ts now excludes src/**/*.cosmos.test.ts so the
default 'pnpm test' run stays green for contributors without Docker.
- backend/vitest.cosmos.config.ts (new) includes ONLY *.cosmos.test.ts,
bumps testTimeout to 30s / hookTimeout to 60s for the real client
round-trips, and locks DB_PROVIDER=cosmos in test env.
- backend/src/cosmos.smoke.cosmos.test.ts (new) covers the four most
important partition-key contracts in NoteLett:
workspaces /userId
notes /workspaceId
note_tasks /workspaceId
note_shares /workspaceId (full create → resolve → delete → null)
Each test also asserts that a wrong-partition-key lookup returns null,
which is the failure mode the in-memory provider cannot simulate.
- backend/package.json adds 'test:cosmos' script.
- .github/workflows/ci.yml gains a backend-cosmos job that boots the
official mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
container as a service, waits for it to be ready (60 × 5s polls of
/_explorer/emulator.pem), then runs pnpm test:cosmos against it.
The job depends on the existing backend job so the emulator only
spins up after unit tests pass.
Verified locally:
- pnpm --filter @notelett/backend test: 380/380 (cosmos suite excluded)
- vitest list --config vitest.cosmos.config.ts: 4 tests under the cosmos
smoke suite, as designed
- pnpm run verify: end-to-end green (backend 380/380, web 96/96,
mobile 97/97)
- ci.yml passes Python yaml.safe_load
CI verification: the new job will execute on the next push. Local
verification against the emulator requires Docker on the dev host.
UI8 deferred deleting the legacy global classes (.surface-card,
.surface-muted, .input-shell, .badge) because 69+ call sites in UI6/UI7
territory (dashboard, search, workspaces, notes detail, chat, palace)
still depend on them. Removing the globals before those screens migrate
would visually break the app.
Instead, ship a one-way ratchet that solves the actually-important
problem: prevent NEW legacy usage from creeping in while existing
sites get migrated.
- scripts/ui-drift-ratchet.sh — reads scripts/ui-drift-baseline.json
and FAILS if any of the four UI drift categories regress above the
tracked baseline. Pure bash, no jq required, works with grep or
ripgrep. Uses the same patterns as scripts/ui-drift-audit.sh.
- scripts/ui-drift-baseline.json — checked-in baseline captured today:
raw controls 38, legacy classes 92, hardcoded colors 0, direct imports 0.
- package.json — adds pnpm run audit:ui:ratchet and
audit:ui:ratchet:update scripts.
- .github/workflows/ci.yml release-guards job — runs the ratchet as a
required step plus the existing audit in report mode.
- docs/UI_UX_PLATFORM_CORE_ROADMAP.md — marks the CI-guard checklist
item complete, documents the path to fully strict mode (drive
baseline to zero, then delete globals.css legacy classes, then flip
audit:ui:strict from advisory to required).
Verified:
- Ratchet at baseline: exits 0
- Synthetic regression (added a file with surface-card + raw <input>):
ratchet correctly exits 1, reporting +1 in each affected category
- pnpm run verify: backend 380/380, web 96/96, mobile 97/97 (no
behavior change)
Restores green build after the May 12 Docker/UI regression.
Root cause: pnpm-workspace.yaml referenced a sibling path
(../learning_ai/learning_ai_common_plat/...) that did not exist on
dev/CI hosts. .pnpmfile.cjs fell back to ../learning_ai_common_plat for
some packages but missed others, so @bytelyst/ui was pulled from a
stale Gitea 0.1.0 tarball with zero exports (breaking web typecheck +
26 tests) and @bytelyst/monitoring was never linked into node_modules
(breaking backend typecheck + 2 test suites).
Changes:
- pnpm-workspace.yaml now references ../learning_ai_common_plat/packages/* directly
- .pnpmfile.cjs swaps DEFAULT/LEGACY common-plat roots so the canonical
path is the default and the older nested path is the fallback
- scripts/docker-prep.sh, scripts/local-smoke.sh, scripts/release-guard-audit.sh
follow the same canonical-first / legacy-fallback pattern
- .github/workflows/ci.yml symlinks directly to ../learning_ai_common_plat
- pnpm-lock.yaml regenerated with @bytelyst/ui@0.1.9 and
@bytelyst/monitoring@0.1.5 linked to the local common-plat checkout
Verified:
- pnpm run verify: backend 373/373, web 96/96, mobile 97/97
- pnpm run audit:release-guards: passes
- backend, web, mobile lint all exit 0 (advisory warnings retained)